# @Version        : 1.0
# @Update Time    : 2025/10/15 00:00
# @File           : default_strategy.py
# @IDE            : PyCharm
# @Desc           : 默认认证策略实现
import uuid
import hashlib
import time
from typing import Any, Callable, Optional


class DefaultStrategy:
    """
    默认认证策略类
    提供token生成、验证等核心功能
    """

    def create_token(self, login_id: Any, login_type: str) -> str:
        """
        创建一个新的token

        Args:
            login_id: 登录ID
            login_type: 登录类型

        Returns:
            生成的token字符串
        """
        # 生成基于UUID和时间戳的token
        raw_token = str(uuid.uuid4()) + str(time.time()) + str(login_id) + login_type
        # 使用SHA256进行哈希，生成固定长度的token
        token = hashlib.sha256(raw_token.encode()).hexdigest()
        return token

    async def generate_unique_token(
        self,
        token_type: str,
        max_try_times: int,
        token_generator: Callable[[], str],
        check_token_function: Callable[[str], bool],
    ) -> str:
        """
        生成一个唯一的token

        Args:
            token_type: token类型
            max_try_times: 最大尝试次数
            token_generator: token生成器函数
            check_token_function: token检查函数

        Returns:
            唯一的token字符串

        Raises:
            Exception: 如果达到最大尝试次数仍无法生成唯一token
        """
        # 尝试生成唯一token
        for i in range(max_try_times):
            # 生成token
            token_value = token_generator()

            # 检查token是否已存在
            exists = await check_token_function(token_value)
            if not exists:
                # token不存在，可以使用
                return token_value

            # 避免频繁生成，短暂暂停
            if i < max_try_times - 1:
                time.sleep(0.01)

        # 达到最大尝试次数仍无法生成唯一token
        raise Exception(
            f"生成 {token_type} 时，达到最大尝试次数 {max_try_times}，无法生成唯一的 token"
        )

    def verify_token(self, token: str) -> bool:
        """
        验证token的格式是否正确

        Args:
            token: 要验证的token

        Returns:
            token是否有效
        """
        # 简单的token格式验证
        if not token or not isinstance(token, str):
            return False

        # SHA256哈希的长度应该是64个字符
        if len(token) != 64:
            return False

        # 检查是否只包含十六进制字符
        try:
            int(token, 16)
            return True
        except ValueError:
            return False

    def extract_token_info(self, token: str) -> Optional[dict]:
        """
        从token中提取信息
        注意：默认策略生成的token是哈希值，无法直接提取原始信息
        此方法仅作为接口兼容性提供

        Args:
            token: token字符串

        Returns:
            token信息字典，如果无法提取则返回None
        """
        # 默认策略生成的token是哈希值，无法提取原始信息
        return None
